using SLProxy;
using libsecondlife;
using libsecondlife.Packets;
using Nwc.XmlRpc;

using System;
using System.Drawing;
using System.Windows.Forms;
using System.Collections;
using System.Net;
using System.Runtime.InteropServices;
using System.Diagnostics;
using System.Reflection;
using System.IO;
using System.Collections.Generic;
using System.Text.RegularExpressions;
using System.Xml.Serialization;
using System.Text.RegularExpressions;

namespace StickyChat
{
    public class StickyServices : Form
    {
        // public info for StickIns
        public Proxy proxy          { get { return myProxy; } }
        public LLUUID AgentID       { get { return agentID; } }
        public LLUUID SessionID     { get { return sessionID; } }
        public Hashtable LoginInfo  { get { return loginInfo; } }

        private Proxy myProxy;
        private LLUUID agentID;
        private LLUUID sessionID;
        private Hashtable loginInfo;

        // private internals
        private string configPath;
        private Settings settings;
        private bool proxyRunning;
        private ProxyConfig proxyConfig;
        private bool loggedIn;
        private string SLpath;
        private TextBox DebugOutput;
        private Button quit;
        private ContextMenuStrip rightClickMenu;
        private System.ComponentModel.IContainer components;
        private ToolStripMenuItem launchSecondLifeToolStripMenuItem;
        private ToolStripMenuItem quitToolStripMenuItem;
        private TabControl StickyChatTabs;
        private ToolStripMenuItem cancelToolStripMenuItem;
        private ToolStripMenuItem reconfigureProxyToolStripMenuItem;
        private ToolStripMenuItem toolStripMenuItem1;
        private ToolStripTextBox PortBox;
        private ToolStripMenuItem startProxyToolStripMenuItem;
        private ToolStripMenuItem stickInsToolStripMenuItem;
        private ToolStripMenuItem loadStickInsToolStripMenuItem;
        private ToolStripMenuItem unloadStickInToolStripMenuItem;
        private List<StickIn> stickins;
        private Hashtable key2name;

        public struct Settings
        {
            public string SLpath;
            public ushort proxy_login_port;
            public static bool operator !=(Settings lhs, Settings rhs)
            {
                return lhs.proxy_login_port != rhs.proxy_login_port
                    || lhs.SLpath != rhs.SLpath;
            }
            public static bool operator ==(Settings lhs, Settings rhs) { return !(lhs != rhs); }
        }

        public static void Main(string[] args)
        {
            Application.Run(new StickyServices(args));
        }

        public StickyServices(string[] args)
        {
            // setup the form
            InitializeComponent();
            // DebugOutput
            this.DebugOutput = new TextBox();
            this.DebugOutput.BackColor = System.Drawing.SystemColors.Window;
            this.DebugOutput.Location = new System.Drawing.Point(0, 0);
            this.DebugOutput.Multiline = true;
            this.DebugOutput.Name = "DebugOutput";
            this.DebugOutput.ReadOnly = true;
            this.DebugOutput.ScrollBars = System.Windows.Forms.ScrollBars.Both;
            this.DebugOutput.Size = new System.Drawing.Size(437, 274);
            Console.SetOut(new TextBoxWriter(this.DebugOutput));

            // configure the proxy
            proxyConfig = new ProxyConfig("StickyChat", "Azurei Ash", args);
            proxyRunning = false;
            loggedIn = false;

            // load StickIns
            string[] plugins = Directory.GetFiles(Application.StartupPath, "*.dll");
            stickins = new List<StickIn>();
            foreach (string plugin in plugins)
            {
                Match match=Regex.Match(plugin, @"([^/\\]*?Sticky[^/\\]*).dll$", RegexOptions.RightToLeft);
                if (match.Success)
                {
                    loadStickIn(plugin);
                }
            }

            // add in the Debug page last
            TabPage dPage = new TabPage();
            dPage.Text = "Debug";
            dPage.Controls.Add(this.DebugOutput);
            StickyChatTabs.TabPages.Add(dPage);
            StickyChatTabs_SelectedIndexChanged(null, null);
            PortBox.Text = proxyConfig.loginPort.ToString();

            // settings stuff
            SLpath = @"C:\Program Files\SecondLife\SecondLife.exe";
            settings = new Settings();
            settings.proxy_login_port = proxyConfig.loginPort;
            settings.SLpath = this.SLpath;

            // load settings
            configPath = Application.StartupPath + @"\config.xml";
            if (File.Exists(configPath))
            {
                Stream reader=null;
                try
                {
                    XmlSerializer xml = new XmlSerializer(typeof(Settings));
                    reader = File.OpenRead(configPath);
                    settings = (Settings)xml.Deserialize(reader);
                    this.SLpath = settings.SLpath;
                    PortBox.Text = (proxyConfig.loginPort = settings.proxy_login_port).ToString();
                }
                catch (Exception ex)
                {
                    Console.WriteLine("Error Loading Settings:" + ex.Message);
                }
                finally
                {
                    if (reader != null)
                    {
                        reader.Close();
                    }
                }
            }

            //load cached keys
            key2name = new Hashtable();
            string namecache=System.Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData)
                + @"\SecondLife\cache\name.cache";
            if (File.Exists(namecache))
            {
                System.IO.StreamReader reader = new StreamReader(namecache);
                string line=reader.ReadLine();
                while (line != null)
                {
                    Match match = Regex.Match(line, @"^(\S+)\s+\S+\s+(\S+)\s+(\S+)$");
                    if (match.Success)
                    {
                        //Console.WriteLine(match.Groups[1].Value + "," + match.Groups[2].Value + " " + match.Groups[3].Value);
                        key2name.Add(new LLUUID(match.Groups[1].Value), match.Groups[2].Value + " " + match.Groups[3].Value);
                    }
                    Console.WriteLine();
                    line = reader.ReadLine();
                }
            }
        }

        private void loadStickIn(string path)
        {
            Console.WriteLine("Loading StickIn: " + path);
            try
            {
                Assembly assembly = Assembly.LoadFile(path);
                foreach (Type type in assembly.GetTypes())
                {
                    if (type.IsPublic && type.IsClass)
                    {
                        if (((IList)type.GetInterfaces()).Contains(typeof(StickIn)))
                        {
                            ConstructorInfo c = type.GetConstructor(new Type[] { typeof(StickyServices) });
                            StickIn s = null;
                            if (c != null)
                            {
                                s = (StickIn)c.Invoke(new Object[] { this });
                            }
                            else
                            {
                                s = (StickIn)Activator.CreateInstance(type);
                            }
                            if (s != null)
                            {
                                stickins.Add(s);
                                unloadStickInToolStripMenuItem.DropDownItems.Add(s.name);
                                if (s is Control)
                                {
                                    TabPage newPage = new TabPage();
                                    newPage.Text = s.name;
                                    newPage.Controls.Add((Control)s);
                                    if (StickyChatTabs.TabPages.Count > 0
                                        && StickyChatTabs.TabPages[StickyChatTabs.TabPages.Count - 1].Text == "Debug")
                                    {
                                        TabPage debug = StickyChatTabs.TabPages[StickyChatTabs.TabPages.Count - 1];
                                        StickyChatTabs.TabPages.Remove(debug);
                                        StickyChatTabs.TabPages.Add(newPage);
                                        StickyChatTabs.TabPages.Add(debug);
                                    }
                                    else
                                    {
                                        StickyChatTabs.TabPages.Add(newPage);
                                    }
                                }
                                if (proxyRunning)
                                {
                                    s.start();
                                }
                            }
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine("Exception loading stickins: " + ex.Message);
            }
        }

        void unloadStickInToolStripMenuItem_DropDownItemClicked(object sender, ToolStripItemClickedEventArgs e)
        {
            unloadStickIn(e.ClickedItem.Text);
        }

        private void unloadStickIn(string name)
        {
            // remove from the context menu
            foreach (ToolStripMenuItem item in unloadStickInToolStripMenuItem.DropDownItems)
            {
                if (item.Text == name)
                {
                    unloadStickInToolStripMenuItem.DropDownItems.Remove(item);
                    break;
                }
            }
            // find and remove StickIn
            foreach (StickIn s in stickins)
            {
                if (s.name == name)
                {
                    if (s is Control)
                    {
                        foreach(TabPage page in StickyChatTabs.TabPages)
                        {
                            if (page.Text == name)
                            {
                                StickyChatTabs.TabPages.Remove(page);
                                break;
                            }
                        }
                    }
                    try
                    {
                        s.stop();
                    }
                    catch (Exception e)
                    {
                        Console.WriteLine("Exception while stopping StickIn " + name + ":" + e.Message);
                        Console.WriteLine(e.StackTrace);
                    }
                    stickins.Remove(s);
                    return;
                }
            }
        }

        private void Login(XmlRpcResponse response)
        {
            loggedIn = true;
            Hashtable values = (Hashtable)response.Value;
            if (values.Contains("agent_id") && values.Contains("session_id"))
            {
                // remember our agentID and sessionID
                agentID = new LLUUID((string)values["agent_id"]);
                sessionID = new LLUUID((string)values["session_id"]);
            }
            loginInfo = values;
        }

        #region Draggable
        Point pointClicked;
        bool mouseDown;
        void StickyChatForm_MouseDown(object sender, MouseEventArgs e)
        {
            if (e.Button == MouseButtons.Left)
            {
                mouseDown = true;
                pointClicked = new Point(e.X, e.Y);
            }
        }

        void StickyChatForm_MouseMove(object sender, MouseEventArgs e)
        {
            if (mouseDown)
            {
                Point p = this.PointToScreen(new Point(e.X, e.Y));
                this.Location = new Point(p.X - this.pointClicked.X,
                                          p.Y - this.pointClicked.Y);
            }
        }

        void StickyChatForm_MouseUp(object sender, MouseEventArgs e)
        {
            if (e.Button == MouseButtons.Left)
            {
                mouseDown = false;
            }
        }

        // This code snippet allows the form to be dragged by empty parts of the form
        // Not really all that useful though
        /*const int WM_LBUTTONDOWN = 0x0201;
        const int WM_NCLBUTTONDOWN = 0x00A1;
        static readonly IntPtr HTCAPTION = (IntPtr)2;
        protected override void WndProc(ref Message m)
        {
            if (m.Msg == WM_LBUTTONDOWN)
            {
                m.Msg = WM_NCLBUTTONDOWN;
                m.WParam = HTCAPTION;
            }
            base.WndProc(ref m);
        }/**/
        #endregion Draggable

        #region Resizing Functions
        private void StickyChatTabs_SelectedIndexChanged(object sender, EventArgs e)
        {
            Size pageSize = StickyChatTabs.TabPages[StickyChatTabs.SelectedIndex].Controls[0].Size;
            StickyChatTabs.Size = new Size(pageSize.Width + this.quit.Size.Width+6, pageSize.Height + StickyChatTabs.ItemSize.Height+6);
            StickyChatTabs.Size = new Size(StickyChatTabs.PreferredSize.Width + this.quit.Size.Width, StickyChatTabs.PreferredSize.Height);

            this.Size = StickyChatTabs.Size;
        }

        void StickyChatForm_Resize(object sender, EventArgs e)
        {
            if (this.WindowState == FormWindowState.Normal && this.ShowInTaskbar == true)
            {
                this.ShowInTaskbar = false;
                this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.None;
            }
        }

        private void StickyChatForm_SizeChanged(object sender, EventArgs e)
        {
            this.quit.Location = new Point(this.Size.Width - this.quit.Size.Width, this.quit.Location.Y);
        }
        #endregion Resizing Functions

        #region Close Functions
        void CloseButton_Click(object sender, EventArgs e)
        {
            if (loggedIn)
            {
                this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedToolWindow;
                this.ShowInTaskbar = true;
                this.WindowState = FormWindowState.Minimized;
            }
            else
            {
                this.Close();
            }
        }

        void StickyChat_FormClosing(object sender, FormClosingEventArgs e)
        {
            if (proxyRunning)
            {
                proxy.Stop();
            }
            StickyServices.Settings newSettings = new Settings();
            newSettings.SLpath = this.SLpath;
            newSettings.proxy_login_port = proxyConfig.loginPort;

            if (settings != newSettings)
            {
                XmlSerializer xml = new XmlSerializer(typeof(StickyServices.Settings));
                Stream writer = File.Open(Application.StartupPath + @"\config.xml", FileMode.Create, FileAccess.Write);
                xml.Serialize(writer, newSettings);
                writer.Close();
            }
        }
        #endregion Close Functions

        #region Context Menu Functions
        void launchSL_Click(object sender, EventArgs e)
        {
            if (!proxyRunning)
            {
                startProxy(null, null);
            }
            if (SLpath.EndsWith(".exe") && File.Exists(SLpath))
            {
                System.Diagnostics.Process.Start(SLpath,
                    "-loginuri http://localhost:" + proxyConfig.loginPort.ToString() + "/");
            }
            else
            {
                OpenFileDialog find = new OpenFileDialog();
                if (find.ShowDialog() == DialogResult.OK)
                {
                    SLpath=find.FileName;
                    try
                    {
                        System.Diagnostics.Process.Start(SLpath,
                            "-loginuri http://localhost:" + proxyConfig.loginPort.ToString() + "/");
                    }
                    catch (Exception ex)
                    {
                        Console.WriteLine(ex.Message);
                    }
                }
            }
        }

        private void startProxy(object sender, EventArgs e)
        {
            if (!proxyRunning)
            {
                myProxy = new Proxy(proxyConfig);

                // set a delegate for when the client logs in
                proxy.SetLoginResponseDelegate(new XmlRpcResponseDelegate(Login));
                proxy.AddDelegate(PacketType.LogoutReply, Direction.Incoming, new PacketDelegate(LogoutReply));
                proxy.AddDelegate(PacketType.UUIDNameReply, Direction.Incoming, UUIDNameReply);

                // start the proxy
                proxy.Start();
                proxyRunning = true;

                startProxyToolStripMenuItem.Enabled = !proxyRunning;
                PortBox.Enabled = !(PortBox.ReadOnly = proxyRunning);

                // start StickIns
                foreach (StickIn stickin in stickins)
                {
                    stickin.start();
                }
            }
        }
        #endregion Context Menu Functions

        private Packet LogoutReply(Packet packet, IPEndPoint sim)
        {
            loggedIn = false;
            return packet;
        }

        private Packet UUIDNameReply(Packet packet, IPEndPoint sim)
        {
            UUIDNameReplyPacket name=(UUIDNameReplyPacket)packet;
            foreach(UUIDNameReplyPacket.UUIDNameBlockBlock block in name.UUIDNameBlock)
            {
                if(!key2name.Contains(block.ID))
                {
                    key2name.Add(block.ID, Helpers.FieldToUTF8String(block.FirstName) + " " + Helpers.FieldToUTF8String(block.LastName));
                }
            }
            return packet;
        }

        private void InitializeComponent()
        {
            this.components = new System.ComponentModel.Container();
            this.quit = new System.Windows.Forms.Button();
            this.rightClickMenu = new System.Windows.Forms.ContextMenuStrip(this.components);
            this.cancelToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
            this.launchSecondLifeToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
            this.startProxyToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
            this.stickInsToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
            this.loadStickInsToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
            this.unloadStickInToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
            this.reconfigureProxyToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
            this.toolStripMenuItem1 = new System.Windows.Forms.ToolStripMenuItem();
            this.PortBox = new System.Windows.Forms.ToolStripTextBox();
            this.quitToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
            this.StickyChatTabs = new System.Windows.Forms.TabControl();
            this.rightClickMenu.SuspendLayout();
            this.SuspendLayout();
            // 
            // quit
            // 
            this.quit.BackColor = System.Drawing.SystemColors.GradientActiveCaption;
            this.quit.Font = new System.Drawing.Font("Microsoft Sans Serif", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
            this.quit.ForeColor = System.Drawing.SystemColors.ActiveCaptionText;
            this.quit.Location = new System.Drawing.Point(94, 0);
            this.quit.Name = "quit";
            this.quit.Size = new System.Drawing.Size(35, 20);
            this.quit.TabIndex = 5;
            this.quit.Text = "!quit";
            this.quit.UseVisualStyleBackColor = false;
            this.quit.Click += new System.EventHandler(this.CloseButton_Click);
            // 
            // rightClickMenu
            // 
            this.rightClickMenu.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {
            this.cancelToolStripMenuItem,
            this.launchSecondLifeToolStripMenuItem,
            this.startProxyToolStripMenuItem,
            this.stickInsToolStripMenuItem,
            this.reconfigureProxyToolStripMenuItem,
            this.quitToolStripMenuItem});
            this.rightClickMenu.Name = "rightClickMenu";
            this.rightClickMenu.Size = new System.Drawing.Size(190, 158);
            // 
            // cancelToolStripMenuItem
            // 
            this.cancelToolStripMenuItem.Name = "cancelToolStripMenuItem";
            this.cancelToolStripMenuItem.Size = new System.Drawing.Size(189, 22);
            this.cancelToolStripMenuItem.Text = "Cancel";
            // 
            // launchSecondLifeToolStripMenuItem
            // 
            this.launchSecondLifeToolStripMenuItem.Name = "launchSecondLifeToolStripMenuItem";
            this.launchSecondLifeToolStripMenuItem.Size = new System.Drawing.Size(189, 22);
            this.launchSecondLifeToolStripMenuItem.Text = "Launch Second Life";
            this.launchSecondLifeToolStripMenuItem.Click += new System.EventHandler(this.launchSL_Click);
            // 
            // startProxyToolStripMenuItem
            // 
            this.startProxyToolStripMenuItem.Name = "startProxyToolStripMenuItem";
            this.startProxyToolStripMenuItem.Size = new System.Drawing.Size(189, 22);
            this.startProxyToolStripMenuItem.Text = "Start Proxy (optional)";
            this.startProxyToolStripMenuItem.Click += new System.EventHandler(this.startProxy);
            // 
            // stickInsToolStripMenuItem
            // 
            this.stickInsToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] {
            this.loadStickInsToolStripMenuItem,
            this.unloadStickInToolStripMenuItem});
            this.stickInsToolStripMenuItem.Name = "stickInsToolStripMenuItem";
            this.stickInsToolStripMenuItem.Size = new System.Drawing.Size(189, 22);
            this.stickInsToolStripMenuItem.Text = "StickIns";
            // 
            // loadStickInsToolStripMenuItem
            // 
            this.loadStickInsToolStripMenuItem.Name = "loadStickInsToolStripMenuItem";
            this.loadStickInsToolStripMenuItem.Size = new System.Drawing.Size(153, 22);
            this.loadStickInsToolStripMenuItem.Text = "Load StickIns";
            this.loadStickInsToolStripMenuItem.Click += new System.EventHandler(this.loadStickInsToolStripMenuItem_Click);
            // 
            // unloadStickInToolStripMenuItem
            // 
            this.unloadStickInToolStripMenuItem.Name = "unloadStickInToolStripMenuItem";
            this.unloadStickInToolStripMenuItem.Size = new System.Drawing.Size(153, 22);
            this.unloadStickInToolStripMenuItem.Text = "Unload StickIn";
            this.unloadStickInToolStripMenuItem.DropDownItemClicked += new System.Windows.Forms.ToolStripItemClickedEventHandler(this.unloadStickInToolStripMenuItem_DropDownItemClicked);
            // 
            // reconfigureProxyToolStripMenuItem
            // 
            this.reconfigureProxyToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] {
            this.toolStripMenuItem1});
            this.reconfigureProxyToolStripMenuItem.Name = "reconfigureProxyToolStripMenuItem";
            this.reconfigureProxyToolStripMenuItem.Size = new System.Drawing.Size(189, 22);
            this.reconfigureProxyToolStripMenuItem.Text = "Reconfigure Proxy";
            // 
            // toolStripMenuItem1
            // 
            this.toolStripMenuItem1.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] {
            this.PortBox});
            this.toolStripMenuItem1.Name = "toolStripMenuItem1";
            this.toolStripMenuItem1.Size = new System.Drawing.Size(152, 22);
            this.toolStripMenuItem1.Text = "Port:";
            // 
            // PortBox
            // 
            this.PortBox.Name = "PortBox";
            this.PortBox.Size = new System.Drawing.Size(100, 21);
            this.PortBox.KeyPress += new System.Windows.Forms.KeyPressEventHandler(this.PortBox_KeyPress);
            // 
            // quitToolStripMenuItem
            // 
            this.quitToolStripMenuItem.Name = "quitToolStripMenuItem";
            this.quitToolStripMenuItem.Size = new System.Drawing.Size(189, 22);
            this.quitToolStripMenuItem.Text = "!quit";
            this.quitToolStripMenuItem.Click += new System.EventHandler(this.CloseButton_Click);
            // 
            // StickyChatTabs
            // 
            this.StickyChatTabs.ContextMenuStrip = this.rightClickMenu;
            this.StickyChatTabs.ItemSize = new System.Drawing.Size(0, 18);
            this.StickyChatTabs.Location = new System.Drawing.Point(0, 0);
            this.StickyChatTabs.Name = "StickyChatTabs";
            this.StickyChatTabs.Padding = new System.Drawing.Point(0, 0);
            this.StickyChatTabs.SelectedIndex = 0;
            this.StickyChatTabs.Size = new System.Drawing.Size(129, 40);
            this.StickyChatTabs.TabIndex = 5;
            this.StickyChatTabs.MouseDown += new System.Windows.Forms.MouseEventHandler(this.StickyChatForm_MouseDown);
            this.StickyChatTabs.MouseMove += new System.Windows.Forms.MouseEventHandler(this.StickyChatForm_MouseMove);
            this.StickyChatTabs.MouseUp += new System.Windows.Forms.MouseEventHandler(this.StickyChatForm_MouseUp);
            this.StickyChatTabs.SelectedIndexChanged += new System.EventHandler(this.StickyChatTabs_SelectedIndexChanged);
            // 
            // StickyServices
            // 
            this.BackColor = System.Drawing.SystemColors.Control;
            this.ClientSize = new System.Drawing.Size(157, 84);
            this.ControlBox = false;
            this.Controls.Add(this.quit);
            this.Controls.Add(this.StickyChatTabs);
            this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.None;
            this.KeyPreview = true;
            this.MaximizeBox = false;
            this.MinimizeBox = false;
            this.Name = "StickyServices";
            this.ShowIcon = false;
            this.ShowInTaskbar = false;
            this.Text = "Sticky Chat";
            this.TopMost = true;
            this.SizeChanged += new System.EventHandler(this.StickyChatForm_SizeChanged);
            this.Resize += new System.EventHandler(this.StickyChatForm_Resize);
            this.MouseUp += new System.Windows.Forms.MouseEventHandler(this.StickyChatForm_MouseUp);
            this.FormClosing += new System.Windows.Forms.FormClosingEventHandler(this.StickyChat_FormClosing);
            this.MouseMove += new System.Windows.Forms.MouseEventHandler(this.StickyChatForm_MouseMove);
            this.MouseDown += new System.Windows.Forms.MouseEventHandler(this.StickyChatForm_MouseDown);
            this.rightClickMenu.ResumeLayout(false);
            this.ResumeLayout(false);

        }

        private void PortBox_KeyPress(object sender, KeyPressEventArgs e)
        {
            if ((int)e.KeyChar == 13)
            {
                if (!proxyRunning)
                {
                    try
                    {
                        proxyConfig.loginPort = Convert.ToUInt16(PortBox.Text);
                    }
                    catch (Exception)
                    {
                        PortBox.Text = proxyConfig.loginPort.ToString();
                    }
                }
                else
                {
                    PortBox.Text = proxyConfig.loginPort.ToString();
                }
            }
        }

        public void SayToUser(string name, string message)
        {
            if (proxy != null)
            {
                ChatFromSimulatorPacket packet = new ChatFromSimulatorPacket();
                packet.ChatData.FromName = Helpers.StringToField(name);
                packet.ChatData.SourceID = LLUUID.Random();
                packet.ChatData.OwnerID = agentID;
                packet.ChatData.SourceType = (byte)2;
                packet.ChatData.ChatType = (byte)1;
                packet.ChatData.Audible = (byte)1;
                packet.ChatData.Position = new LLVector3(0, 0, 0);
                packet.ChatData.Message = Helpers.StringToField(message);
                proxy.InjectPacket(packet, Direction.Incoming);
            }
        }

        public string getName(LLUUID key)
        {
            if (key2name.Contains(key))
            {
                return key2name[key].ToString();
            }
            if (proxy != null)
            {
                UUIDNameRequestPacket getName = new UUIDNameRequestPacket();
                getName.UUIDNameBlock = new UUIDNameRequestPacket.UUIDNameBlockBlock[1];
                getName.UUIDNameBlock[0] = new UUIDNameRequestPacket.UUIDNameBlockBlock();
                getName.UUIDNameBlock[0].ID = key;
                proxy.InjectPacket(getName, Direction.Outgoing);
            }
            return "";
        }

        private void loadStickInsToolStripMenuItem_Click(object sender, EventArgs e)
        {
            OpenFileDialog find = new OpenFileDialog();
            find.InitialDirectory = Application.StartupPath;
            if (find.ShowDialog() == DialogResult.OK)
            {
                loadStickIn(find.FileName);
            }
        }
    }
}